home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / mawk10.zip / PRINT.C < prev    next >
C/C++ Source or Header  |  1991-10-05  |  8KB  |  304 lines

  1.  
  2. /********************************************
  3. print.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the AWK programming language.
  8.  
  9. Mawk is distributed without warranty under the terms of
  10. the GNU General Public License, version 2, 1991.
  11. ********************************************/
  12.  
  13. /* $Log:    print.c,v $
  14.  * Revision 3.4.1.1  91/09/14  17:24:01  brennan
  15.  * VERSION 1.0
  16.  * 
  17.  * Revision 3.4  91/08/13  06:51:57  brennan
  18.  * VERSION .9994
  19.  * 
  20.  * Revision 3.3  91/06/28  04:17:24  brennan
  21.  * VERSION 0.999
  22.  * 
  23.  * Revision 3.2  91/06/10  15:59:29  brennan
  24.  * changes for V7
  25.  * 
  26.  * Revision 3.1  91/06/07  10:28:06  brennan
  27.  * VERSION 0.995
  28.  * 
  29.  * Revision 2.4  91/05/28  15:18:07  brennan
  30.  * removed STRING_BUFF back to temp_buff.string_buff
  31.  * 
  32.  * Revision 2.3  91/05/28  09:05:04  brennan
  33.  * removed main_buff
  34.  * 
  35.  * Revision 2.2  91/04/09  12:39:23  brennan
  36.  * added static to funct decls to satisfy STARDENT compiler
  37.  * 
  38.  * Revision 2.1  91/04/08  08:23:43  brennan
  39.  * VERSION 0.97
  40.  * 
  41. */
  42.  
  43. #include "mawk.h"
  44. #include "bi_vars.h"
  45. #include "bi_funct.h"
  46. #include "memory.h"
  47. #include "field.h"
  48. #include "scan.h"
  49. #include "files.h"
  50.  
  51. /*  static  functions */
  52. static void  PROTO( print_cell, (CELL *, FILE *) ) ;
  53. static void  PROTO( do_printf, (FILE *, char *, unsigned, CELL *) ) ;
  54. static void  PROTO( do_sprintf, (char *, unsigned, CELL *) ) ;
  55.  
  56.  
  57. static void print_cell(p, fp)
  58.   register CELL *p ;
  59.   register FILE *fp ;
  60. { register int len ;
  61.   
  62.   switch( p->type )
  63.   {
  64.     case C_NOINIT : break ;
  65.     case C_MBSTRN :
  66.     case C_STRING :
  67.     case C_STRNUM :
  68.         switch( len = string(p)->len )
  69.         {
  70.           case 0 :  break ;
  71.           case 1 :
  72.                     putc(string(p)->str[0],fp) ;
  73.                     break ;
  74.  
  75.           default :
  76.                     fwrite(string(p)->str, SIZE_T(1), SIZE_T(len), fp) ;
  77.         }
  78.         break ;
  79.  
  80.     case C_DOUBLE :
  81.         fprintf(fp, string(field + OFMT)->str, p->dval) ;
  82.         break ;
  83.  
  84.     default :
  85.         bozo("bad cell passed to print_cell") ;
  86.   }
  87. }
  88.  
  89. /* on entry to bi_print or bi_printf the stack is:
  90.  
  91.    sp[0] = an integer k
  92.        if ( k < 0 )  output is to a file with name in sp[-1]
  93.        { so open file and sp -= 2 }
  94.  
  95.    sp[0] = k >= 0 is the number of print args
  96.    sp[-k]   holds the first argument 
  97. */
  98.  
  99. CELL *bi_print(sp)
  100.   CELL *sp ; /* stack ptr passed in */
  101. { register CELL *p ;
  102.   register int k ;
  103.   FILE *fp ;
  104.  
  105.   if ( (k = sp->type) < 0 )
  106.   { if ( (--sp)->type < C_STRING ) cast1_to_s(sp) ;
  107.     fp = (FILE *) file_find( string(sp), k ) ;
  108.     free_STRING(string(sp)) ;
  109.     k = (--sp)->type ;
  110.   }
  111.   else  fp = stdout ;
  112.  
  113.   if ( k )  
  114.   { p = sp - k ; /* clear k variables off the stack */
  115.     sp = p - 1 ;
  116.     while ( k-- > 1 ) 
  117.     { print_cell(p,fp) ; print_cell(bi_vars+OFS,fp) ;
  118.       cell_destroy(p) ; p++ ; }
  119.     
  120.     print_cell(p, fp) ;  cell_destroy(p) ;
  121.   }
  122.   else  
  123.   { sp-- ;
  124.     print_cell( &field[0], fp )  ; }
  125.  
  126.   print_cell( bi_vars + ORS , fp) ;
  127.   return sp ;
  128. }
  129.   
  130. /* the contents of format are preserved */
  131. static void do_printf( fp, format, argcnt, cp)
  132.   FILE *fp ;
  133.   char *format ; unsigned argcnt ;
  134.   CELL *cp ;  /* ptr to an array of arguments ( on the eval stack) */
  135. { register char *q ;
  136.   char  save ;
  137.   char *p = format ;
  138.  
  139.   while ( 1 )
  140.   { if ( ! (q = strchr(p, '%'))  )
  141.        if ( argcnt == 0 )
  142.        { fputs(p, fp) ; return ; }
  143.        else
  144.          rt_error("too many arguments in call to printf(%s)", 
  145.               format ) ; 
  146.  
  147.     if ( * ++q == '%' )
  148.     { fwrite( p, SIZE_T(q-p), SIZE_T(1), fp) ; p = q+1 ; continue ; }
  149.  
  150.     if ( argcnt == 0 )
  151.         rt_error("too few arguments in call to printf(%s)", format) ; 
  152.  
  153.     if ( *q == '-' ) q++ ;
  154.     while ( scan_code[*(unsigned char*)q] == SC_DIGIT )  q++ ;
  155.     if ( *q == '.' )
  156.     { q++ ;
  157.       while ( scan_code[*(unsigned char*)q] == SC_DIGIT ) q++ ; }
  158.     
  159.     save = * ++q ;  *q = 0 ;
  160.     switch( q[-1] )
  161.     {
  162.       case 'c' :  
  163.       case 'd' :
  164.       case 'o' :
  165.       case 'x' :
  166.             if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
  167.             (void) fprintf(fp, p, (int) cp->dval) ;
  168.             break ;
  169.       case 'e' :
  170.       case 'g' :
  171.       case 'f' :
  172.             if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
  173.             (void) fprintf(fp, p, cp->dval) ;
  174.             break ;
  175.       case  's' :
  176.             if ( cp->type < C_STRING ) cast1_to_s(cp) ;
  177.             (void) fprintf(fp, p, string(cp)->str) ;
  178.             break ;
  179.       default :
  180.             rt_error("bad format string in call to printf(%s)",
  181.               format) ;
  182.     }
  183.     *q = save ; p = q ; argcnt-- ; cp++ ;
  184.   }
  185. }
  186.  
  187.  
  188. CELL *bi_printf(sp)
  189.   register CELL *sp ;
  190. { register int k ;
  191.   register CELL *p ;
  192.   FILE *fp ;
  193.  
  194.   if ( (k = sp->type) < 0 )
  195.   { if ( (--sp)->type < C_STRING ) cast1_to_s(sp) ;
  196.     fp = (FILE *) file_find( string(sp), k ) ;
  197.     free_STRING(string(sp)) ;
  198.     k = (--sp)->type ;
  199.   }
  200.   else  fp = stdout ;
  201.  
  202.   sp -= k-- ; /* sp points at the format string */
  203.   if ( sp->type < C_STRING )  cast1_to_s(sp) ;
  204.   do_printf(fp, string(sp)->str, k, sp+1) ;
  205.  
  206.   free_STRING(string(sp)) ;
  207.   for ( p = sp+1 ; k-- ; p++ )  cell_destroy(p) ;
  208.   return --sp ;
  209. }
  210.  
  211. CELL *bi_sprintf(sp)
  212.   CELL *sp ;
  213. { CELL *p ;
  214.   int argcnt = sp->type ;
  215.   void do_sprintf() ;
  216.  
  217.   sp -= argcnt-- ; /* sp points at the format string */
  218.   if ( sp->type < C_STRING )  cast1_to_s(sp) ;
  219.   do_sprintf(string(sp)->str, argcnt, sp+1) ;
  220.  
  221.   free_STRING(string(sp)) ;
  222.   for ( p = sp+1 ; argcnt-- ; p++ )  cell_destroy(p) ;
  223.  
  224.   sp->ptr = (PTR) new_STRING( temp_buff.string_buff ) ;
  225.   return sp ;
  226. }
  227.  
  228.  
  229. /* the contents of format are preserved */
  230. static void do_sprintf( format, argcnt, cp)
  231.   char *format ; 
  232.   unsigned argcnt ;
  233.   CELL *cp ;
  234. { register char *q ;
  235.   char  save ;
  236.   char *p = format ;
  237.   register char *target = temp_buff.string_buff ;
  238.  
  239.   temp_buff.string_buff[SPRINTF_SZ-1] = *target = 0 ;
  240.   while ( 1 )
  241.   { if ( ! (q = strchr(p, '%'))  )
  242.        if ( argcnt == 0 )
  243.        { strcpy(target, p) ; 
  244.          /* check the result is not too large */
  245.          if ( temp_buff.string_buff[SPRINTF_SZ-1] != 0 )
  246.          { /* This may have damaged us -- try to croak out an error
  247.               message and exit */
  248.            rt_overflow("sprintf buffer", SPRINTF_SZ) ;
  249.          }
  250.          return ; 
  251.        }
  252.        else
  253.          rt_error("too many arguments in call to sprintf(%s)", 
  254.              format ) ; 
  255.  
  256.     if ( * ++q == '%' )
  257.     { unsigned len ;
  258.  
  259.       (void) memcpy(target, p, SIZE_T(len = q-p) ) ;
  260.       p = q + 1 ; *(target += len) = 0 ;
  261.       continue ;
  262.     }
  263.  
  264.     if ( argcnt == 0 )
  265.       rt_error("too few arguments in call to sprintf(%s)", format) ; 
  266.  
  267.     if ( *q == '-' ) q++ ;
  268.     while ( scan_code[*(unsigned char*)q] == SC_DIGIT )  q++ ;
  269.     if ( *q == '.' )
  270.     { q++ ;
  271.       while ( scan_code[*(unsigned char*)q] == SC_DIGIT ) q++ ; }
  272.     
  273.     save = * ++q ;  *q = 0 ;
  274.     switch( q[-1] )
  275.     {
  276.       case 'c' :  
  277.       case 'd' :
  278.       case 'o' :
  279.       case 'x' :
  280.             if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
  281.             (void) sprintf(target, p, (int) cp->dval ) ;
  282.             target += strlen(target) ;
  283.             break ;
  284.       case 'e' :
  285.       case 'g' :
  286.       case 'f' :
  287.             if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
  288.             (void) sprintf(target, p, cp->dval ) ;
  289.             target += strlen(target) ;
  290.             break ;
  291.       case  's' :
  292.             if ( cp->type < C_STRING ) cast1_to_s(cp) ;
  293.             (void) sprintf(target, p, string(cp)->str ) ;
  294.             target += strlen(target) ;
  295.             break ;
  296.       default :
  297.             rt_error("bad format string in call to sprintf(%s)", 
  298.                 format) ;
  299.     }
  300.     *q = save ; p = q ; argcnt-- ; cp++ ;
  301.   }
  302. }
  303.  
  304.